﻿namespace WinnerCMS.Common.Security
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Threading;

    internal static class CssEncoder
    {
        private static char[][] characterValues;
        private static readonly ReaderWriterLockSlim SyncLock = new ReaderWriterLockSlim();
        private const char UnicodeReplacementCharacter = '�';

        private static void AcquireReadLock()
        {
            SyncLock.EnterReadLock();
        }

        private static void AcquireWriteLock()
        {
            SyncLock.EnterWriteLock();
        }

        private static IEnumerable CssSafeList()
        {
            int iteratorVariable0 = 0x30;
        Label_PostSwitchInIterator: ;
            if (iteratorVariable0 <= 0x39)
            {
                yield return iteratorVariable0;
                iteratorVariable0++;
                goto Label_PostSwitchInIterator;
            }
            for (int i = 0x41; i <= 90; i++)
            {
                yield return i;
            }
            for (int j = 0x61; j <= 0x7a; j++)
            {
                yield return j;
            }
        }

        internal static string Encode(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return input;
            }
            if (characterValues == null)
            {
                InitialiseSafeList();
            }
            char[] chArray = input.ToCharArray();
            int length = 0;
            int num2 = chArray.Length;
            char[] chArray2 = new char[num2 * 7];
            AcquireReadLock();
            try
            {
                for (int i = 0; i < num2; i++)
                {
                    char c = chArray[i];
                    int num4 = chArray[i];
                    switch (num4)
                    {
                        case 0xfffe:
                        case 0xffff:
                            chArray2[length++] = (char)0xfffd;
                            break;

                        default:
                            if (char.IsHighSurrogate(c))
                            {
                                if ((i + 1) == num2)
                                {
                                    chArray2[length++] = (char)0xfffd;
                                }
                                else
                                {
                                    char ch2 = chArray[i + 1];
                                    char ch3 = chArray[i + 1];
                                    if (!char.IsLowSurrogate(ch2))
                                    {
                                        chArray2[length++] = (char)0xfffd;
                                    }
                                    else
                                    {
                                        i++;
                                        long num5 = (0x10000 + ((num4 - 0xd800) * 0x400)) + (ch3 - 0xdc00);
                                        char[] chArray3 = SafeList.SlashThenSixDigitHexValueGenerator(num5);
                                        for (int j = 0; j < chArray3.Length; j++)
                                        {
                                            chArray2[length++] = chArray3[j];
                                        }
                                    }
                                }
                            }
                            else if (char.IsLowSurrogate(c))
                            {
                                chArray2[length++] = (char)0xfffd;
                            }
                            else if (num4 > (characterValues.Length - 1))
                            {
                                char[] chArray4 = SafeList.SlashThenSixDigitHexValueGenerator(num4);
                                for (int k = 0; k < chArray4.Length; k++)
                                {
                                    chArray2[length++] = chArray4[k];
                                }
                            }
                            else if (characterValues[num4] != null)
                            {
                                char[] chArray5 = characterValues[num4];
                                for (int m = 0; m < chArray5.Length; m++)
                                {
                                    chArray2[length++] = chArray5[m];
                                }
                            }
                            else
                            {
                                chArray2[length++] = c;
                            }
                            break;
                    }
                }
            }
            finally
            {
                ReleaseReadLock();
            }
            return new string(chArray2, 0, length);
        }

        private static void InitialiseSafeList()
        {
            AcquireWriteLock();
            try
            {
                if (characterValues == null)
                {
                    characterValues = SafeList.Generate(0xff, new SafeList.GenerateSafeValue(SafeList.SlashThenSixDigitHexValueGenerator));
                    SafeList.PunchSafeList(ref characterValues, CssSafeList());
                }
            }
            finally
            {
                ReleaseWriteLock();
            }
        }

        private static void ReleaseReadLock()
        {
            SyncLock.ExitReadLock();
        }

        private static void ReleaseWriteLock()
        {
            SyncLock.ExitWriteLock();
        }

    }
}

